// pages/music-play/index.js
// 导入状态管理
// 1、audioContext：歌曲播放的实例
// 2、playerStore：歌曲的状态管理
import { audioContext, playerStore } from "../../../store/index";

// 用来记录播放模式图标的名字，要保持一一对应
// 0：order 顺序播放
// 1：repeat 单曲循环
// 2：random 随机播放
const playModeName = ["order", "repeat", "random"]

Page({
  data: {
    currentSong: {}, // 当前歌曲的数据
    lyricData: [], // 当前歌曲的歌词数据
    currentLyricIndex: 0, // 当前歌词数组的索引
    currentLyricText: "", // 当前时间点的歌词句

    currentPage: 0, // 记录当前页数：0 是歌曲页；1 是歌词页
    contentHeight: 0, // 动态计算页面内容区域的高度
    lyricScrollTop: 0, // 歌词页面，滚动区域需要滚动的距离

    isMusicLyric: true, // 控制歌曲页面中歌词是否显示
    isPlaying: false, // 播放状态，true 为播放，false 为暂停

    sliderValue: 0, // 进度条的长度数据
    durationTime: 0, // 歌曲总时长
    currentTime: 0, // 当前播放的时长
    isSliderChanging: false, // 判断当前进度条是否正在改变，true 就是正在改变

    playModeName: "order", // 播放模式的图标名
    playModeIndex: 0, // 播放模式：0 表示循环播放；1 表示单曲循环；2 表示随机播放
  },

  // ======================================== 生命周期函数 ========================================
  onLoad() {
    // 1、调用通过状态管理获取歌曲数据的函数
    this.setupPlayerStoreListener();

    // 2、动态计算内容高度
    const globalData = getApp().globalData; // 获取全局的数据对象
    const screenHeight = globalData.screenHeight; // 整个屏幕的高度
    const statusBarHeight = globalData.statusBarHeight; // 状态栏的高度
    const navBarHeight = globalData.navBarHeight; // 导航栏的高度
    const contentHeight = screenHeight - statusBarHeight - navBarHeight; // 内容区域的高度
    const deviceRadio = globalData.deviceRadio; // 设备高宽比
    this.setData({ contentHeight, isMusicLyric: deviceRadio > 1.8 });
  },
 
  // ======================================== 数据监听 ========================================
  // 获取歌曲状态管理中的数据
  setupPlayerStoreListener() {
    // 1、监听 currentSong、lyricData、durationTime 数据
    playerStore.onStates(["currentSong", "lyricData", "durationTime"], ({
      currentSong,
      lyricData,
      durationTime
    }) => {
      // 当哪一个数据改变了，才更新该数据
      if(currentSong) this.setData({ currentSong });
      if(lyricData) this.setData({ lyricData });
      if(durationTime) this.setData({ durationTime });
    });

    // 2、监听 currentTime、currentLyricIndex、currentLyricText 数据
    playerStore.onStates(["currentTime", "currentLyricIndex", "currentLyricText"], ({
      currentTime,
      currentLyricIndex,
      currentLyricText
    }) => {
      // 1、监听当前播放时间变化
      if(currentTime && !this.data.isSliderChanging) {
        // 当 currentTime 更新有值了，并且当前的进度条没有在改变
        const sliderValue = currentTime / this.data.durationTime * 100; // 进度条的数据
        this.setData({ currentTime, sliderValue });
      }

      // 2、监听歌词变化
      if(currentLyricIndex) {
        // 更新当前歌词的索引和歌词滚动区域距离顶部的距离
        this.setData({ currentLyricIndex, lyricScrollTop: currentLyricIndex * 35 });
      }
      if(currentLyricText) {
        // 更新歌词
        this.setData({ currentLyricText });
      }
    });

    // 3、监听 playModeIndex、isPlaying 数据
    playerStore.onStates(["playModeIndex", "isPlaying"], ({
      playModeIndex,
      isPlaying
    }) => {
      // 当状态管理改变再更新 data 数据
      if(playModeIndex !== undefined) {
        this.setData({ playModeIndex, playModeName: playModeName[playModeIndex] });
      }
      if(isPlaying !== undefined) {
        this.setData({ isPlaying });
      }
    });
  },

  // ======================================== 事件处理 ========================================
  // 返回按钮触发的事件
  handleBack() {
    wx.navigateBack({
      delta: 1
    });
  },

  // 内容区域左右滑动改变时候触发的事件
  handleContentChange(event) {
    const current = event.detail.current; // 获取当前的页数
    this.setData({ currentPage: current }); // 设置当前的页数
  },
  
  // 点击进度条改变触发的事件
  handleSliderChange(event) {
    // 1、获取 slider 变化的值
    const value = event.detail.value;

    // 2、滑动进度条后，需要进行播放的歌曲时间位置
    const currentTime = this.data.durationTime * value / 100; // 百分比

    // 3、设置歌曲播放到 currentTime 时间位置
    // audioContext.pause(); // 暂停歌曲
    audioContext.seek(currentTime / 1000); // 播放具体时间的歌曲，注意 seek 方法的参数单位是秒
    playerStore.setState("isPlaying", true);
    
    // 4、记录最新的 sliderValue、设置当前进度条没有进行修改
    this.setData({ sliderValue: value, isSliderChanging: false });
  },

  // 进度条正在改变时候触发的事件
  handleSliderChanging(event) {
    const value = event.detail.value; // 获取进度条的位置数据
    const currentTime = this.data.durationTime * value / 100; // 获取当前拖动到的时间

    // 设置当前进度条正在修改、设置当前播放到的时间
    this.setData({ isSliderChanging: true, currentTime }); 
  },

  // 点击切换播放模式触发的事件
  handleModeClick() {
    let playModeIndex = this.data.playModeIndex + 1; // 计算点击播放模式后，下一个模式的索引

    // 当前所以已经是 2 的话，再 +1，就让其重新变为 0
    if(playModeIndex === 3) playModeIndex = 0;

    // 设置 playerStore 中的 playModeIndex
    playerStore.setState("playModeIndex", playModeIndex); 
  },

  // 点击播放暂停按钮触发的事件
  handlePlayClick() {
    playerStore.dispatch("changeMusicPlayStateAction", !this.data.isPlaying);
  },

  // 点击上一首按钮触发的事件
  handlePrevClick() {
    playerStore.dispatch("changeNewMusicAction", false);
  },

  // 点击下一首按钮触发的事件
  handleNextClick() {
    playerStore.dispatch("changeNewMusicAction");
  }
});
